#!/bin/bash  
  
# CMD_OPTION 命令参数 如--log  
CMD_OPTION="$2"  
  
# APP_NAME 应用程序名称 推荐小于15个字符
APP_NAME="${artifactId}"
# 定义应用程序的路径和名称  
APP_PATH="/data/${artifactId}"
JAR_FILE="${artifactId}-${version}.${packaging}"
  
# 定义日志文件路径  
LOG_DIR="$APP_PATH/logs/"  
LOG_FILE="$LOG_DIR/stdout"  
# 存储进程ID的文件  
PID_FILE="$APP_PATH/${APP_NAME}.pid"

# 命令行参数设置

# JAVA_OPTION JVM参数设置
# JAVA_OPTION="-Xms128m -Xmx256m -XX:MaxPermSize=64m"
JAVA_OPTION=""

# REMOTE_JVM_DEBUG 远程调试参数设置
#REMOTE_JVM_DEBUG="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"

#spring boot 参数陪吹
# SPRING_BOOT_OPTION
#SPRING_BOOT_OPTION="--spring.profiles.active=test"
#库文件目录
LIB="$APP_PATH/lib"
#spring boot loader.path
LOADER_PATH="-Dloader.path=$LIB"

# 定义JAR执行命令
JAR_CMD="java -Dapp=$APP_NAME $LOADER_PATH -jar $JAVA_OPTION $REMOTE_JVM_DEBUG $APP_PATH/$JAR_FILE $SPRING_BOOT_OPTION"
  
# 获取当前应用程序的pid（如果存在）  
function get_pid {  
    if [ -f "$PID_FILE" ]; then  
        cat "$PID_FILE"  
    else  
        echo "0"  
    fi  
}  
  
# 启动应用程序  
function start() {
    echo "启动 $APP_NAME..."  
    # 创建日志目录  
    if [ ! -d ${LOG_DIR} ]; then  
        mkdir -p ${LOG_DIR}  
    fi  
    # 启动应用并保存pid  
    nohup $JAR_CMD > $LOG_FILE 2>&1 &  
    echo $! > $PID_FILE  
    echo "$APP_NAME 启动了."  
    # 检查是否需要显示日志  
    if [[ "$CMD_OPTION" == "-g" || "$CMD_OPTION" == "--log" ]]; then  
        tail -fn500 "$LOG_FILE"  
    fi  
}  
  
# 停止应用程序
function stop() {
    echo "正在停止 $APP_NAME..."
    pid=$(get_pid)
    if [ "$pid" -ne 0 ]; then
        # 发送终止信号给进程
        kill "$pid"

        # 等待进程关闭，最多等待10秒
        count=0
        while [ $count -lt 10 ]; do
            # 检查 /proc/$pid 是否存在来判断进程是否仍在运行
            if [ ! -d "/proc/$pid" ]; then
                # 进程不存在，退出循环
                break
            fi
            echo "$APP_NAME 正在停止中..."
            sleep 1
            count=$((count + 1))
        done

        # 检查进程是否最终关闭
        if [ ! -d "/proc/$pid" ]; then
            echo "$APP_NAME 已成功停止."
            # 清除pid文件
            rm -f "$PID_FILE"
        else
            echo "$APP_NAME 停止失败，请手动处理."
            echo "这里可以选择是否发送 SIGKILL 信号，但需要谨慎使用"
            echo "kill -9 $pid"
        fi
    else
        echo "$APP_NAME 未运行."
    fi
}
  
# 重启应用程序  
function restart() {  
    echo "重启 $APP_NAME..."  
    stop  
    start  
    echo "$APP_NAME 重启了."  
}  
  
# 检查应用程序状态  
function status() {  
    pid=$(get_pid)  
    if [ $pid -ne 0 ]; then  
        echo "$APP_NAME 正在运行，PID: $pid."
        # 从/proc文件系统获取完整的命令行  优化一个更好看的格式
        cmdline=$(cat /proc/$pid/cmdline | sed 's/java\x0/java /g' | sed 's/-jar\x0/-jar /g' | sed 's/\x0/\n/g')
        echo "命令行:\n$cmdline"
        # 显示其他进程信息
        echo
        ps -p $pid -o pid,comm,%mem,%cpu  
    else  
        echo "$APP_NAME 已经停止."  
    fi  
}  
  
# 根据命令行参数执行相应的操作  
case "$1" in  
    start) start ;;  
    stop) stop ;;  
    restart) restart ;;  
    status) status ;;  
    *) echo "Usage: $0 {start|stop|restart|status} [-g|--log]" && exit 1 ;;  
esac